/**
 * The MIT License (MIT)
 *
 * Copyright (c) 2021 Marcus Britanicus (https://gitlab.com/marcusbritanicus)
 * Copyright (c) 2021 Abrar (https://gitlab.com/s96Abrar)
 *
 * Permission is hereby granted, free of charge, to any person obtaining a copy
 * of this software and associated documentation files (the "Software"), to deal
 * in the Software without restriction, including without limitation the rights
 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 * copies of the Software, and to permit persons to whom the Software is
 * furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included in all
 * copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
 * SOFTWARE.
 **/

#include <QtWidgets>

#include <wayland-client.h>
#include <wayqt/WayQtUtils.hpp>
#include <wayqt/Registry.hpp>
#include <wayqt/WindowManager.hpp>
#include <wayqt/ToplevelManager.hpp>

int main( int argc, char *argv[] ) {
    QApplication *app = new QApplication( argc, argv );

    app->setDesktopFileName( "wayqt-test.desktop" );

    WQt::Registry *reg = new WQt::Registry( WQt::Wayland::display() );

    reg->setup();

    WQt::WindowManager *winMgr = nullptr;

    if ( reg->waitForInterface( WQt::Registry::WindowManagerInterface ) ) {
        winMgr = reg->windowManager();
    }

    else {
        return 1;
    }

    QMap<uint32_t, bool> prints;

    // /** Fresh toplevels */
    // QObject::connect(
    //     winMgr, &WQt::ToplevelManager::newToplevel, [ = ] ( WQt::Toplevel *handle ) mutable {
    //         qDebug() << "> New top-level:" << handle->uuid();
    //         QObject::connect(
    //             handle, &WQt::Toplevel::titleChanged, [ = ] ( QString o, QString n ) mutable {
    //                 if ( handle->title().size() * handle->appId().size() and prints.value( handle->uuid()
    // ) ) {
    //                     qDebug() << "> New toplevel" << handle->uuid() << handle->title() <<
    // handle->appId();
    //                     prints[ handle->uuid() ] = true;
    //                 }
    //             }
    //         );
    //
    //         QObject::connect(
    //             handle, &WQt::Toplevel::appIdChanged, [ = ] ( QString o, QString n ) mutable {
    //                 if ( handle->title().size() * handle->appId().size() and prints.value( handle->uuid()
    // ) ) {
    //                     qDebug() << "> New toplevel" << handle->title() << handle->appId();
    //                     prints[ handle->uuid() ] = true;
    //                 }
    //             }
    //         );
    //
    //         QObject::connect(
    //             handle, &WQt::Toplevel::processInfo, [ = ] ( uint32_t pid, uint32_t uid, uint32_t gid ) {
    //                 qDebug() << ">> Proc Info:" << handle->uuid() << handle->appId() << handle->title()
    // << pid << uid << gid;
    //             }
    //         );
    //
    //         handle->setup();
    //         handle->getProcessInfo();
    //     }
    // );
    //
    // /** These are the toplevels that we received after the sendAllToplevels() request. */
    // QObject::connect(
    //     winMgr, &WQt::ToplevelManager::toplevel, [ = ] ( WQt::Toplevel *handle ) mutable {
    //         QObject::connect(
    //             handle, &WQt::Toplevel::titleChanged, [ = ] ( QString, QString ) mutable {
    //                 if ( handle->title().size() * handle->appId().size() and prints.value( handle->uuid()
    // ) ) {
    //                     qDebug() << "Toplevel" << handle->title() << handle->appId();
    //                     prints[ handle->uuid() ] = true;
    //                 }
    //             }
    //         );
    //
    //         QObject::connect(
    //             handle, &WQt::Toplevel::appIdChanged, [ = ] ( QString, QString ) mutable {
    //                 if ( handle->title().size() * handle->appId().size() and prints.value( handle->uuid()
    // ) ) {
    //                     qDebug() << "Toplevel" << handle->title() << handle->appId();
    //                     prints[ handle->uuid() ] = true;
    //                 }
    //             }
    //         );
    //
    //         handle->setup();
    //     }
    // );
    //
    // /** These are the toplevels that we received after the sendAllToplevels() request. */
    // QObject::connect(
    //     winMgr, &WQt::ToplevelManager::receivedToplevels, [ = ] ( WQt::Toplevels toplevels ) {
    //         qDebug() << "Toplevel count:" << toplevels.count();
    //         for ( WQt::Toplevel *hndl: toplevels ) {
    //             qApp->processEvents();
    //
    //             qDebug() << "  --> Toplevel" << hndl->title() << hndl->appId();
    //
    //             QObject::connect(
    //                 hndl, &WQt::Toplevel::viewCaptured, [ = ] ( QImage img ) {
    //                     img.save( "/tmp/" + hndl->appId() + QString( "%1" ).arg( hndl->uuid() ) + ".png"
    // );
    //                 }
    //             );
    //
    //             hndl->capture();
    //         }
    //     }
    // );

    winMgr->setup();

    QTimer::singleShot(
        2000,
        [ = ] () {
            qDebug() << "Toplevel count:" << winMgr->windowHandles().length();
            for ( WQt::WindowHandle *handle: winMgr->windowHandles() ) {
                QObject::connect(
                    handle, &WQt::WindowHandle::appIdChanged, [ = ] () {
                        qDebug() << "> AppID Change:" << handle->appId();
                    }
                );
                handle->setup();
            }
        }
    );

    // winMgr->sendAllToplevels();
    //
    // QTimer::singleShot(
    //     5000,
    //     [ = ] () {
    //         qDebug() << "Resending all toplevels";
    //         winMgr->sendAllToplevels();
    //     }
    // );

    return app->exec();
}
